/*
 *  Copyright 2011 yura.
 * 
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 * 
 *       http://www.apache.org/licenses/LICENSE-2.0
 * 
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *  under the License.
 */

package org.opu.vcforms.transform_t2d.util;

import java.io.ByteArrayInputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.logging.Level;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.opu.vcforms.template.util.Loadable;
import org.opu.vcforms.transform_t2d.Logger;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

/**
 *
 * @author yura
 */
public class XmlUtil {
    public static final String CUSTOM_XML_URI = "http://yura.opu.ua/vcforms/transform";
    public static final SAXParser sp;
    public static final SAXParserFactory spf;

    static {
        try {
            // Create a JAXP "parser factory" for creating SAX parsers
            spf = SAXParserFactory.newInstance();

            // Configure the parser factory for the type of parsers we require
            spf.setValidating(false); // No validation required

            // Now use the parser factory to create a SAXParser object
            // Note that SAXParser is a JAXP class, not a SAX class
            sp = spf.newSAXParser();
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    }

    public void parse(byte[] data, org.xml.sax.helpers.DefaultHandler handler){
        // Create a SAX input source for the file argument
        InputSource input;
        try {
            input = new InputSource(new InputStreamReader(
                    new ByteArrayInputStream(data), Loadable.CHARSET));
        } catch (UnsupportedEncodingException ex) {
            throw new RuntimeException(ex);
        }

        // Tell the parser to parse the input and notify the handler
        try {
            sp.parse(input, handler);
        } catch (Exception ex) {
            throw new IllegalArgumentException("Bad parse output", ex);
        }
    }

    protected static abstract class DefaultHandler extends org.xml.sax.helpers.DefaultHandler{
        public static final String TEXT_TAG = "t";

        @Override
        public void warning(SAXParseException exception) {
            Logger.err(DocxUtil.class.getCanonicalName() + "<convertOOXMLToDataXML>"
                    + "[WARNING]: line " + exception.getLineNumber() + ", row"
                    + exception.getColumnNumber() + ": " + exception.getMessage());
        }

        // This method is called when errors occur
        @Override
        public void error(SAXParseException exception) {
            Logger.err(DocxUtil.class.getCanonicalName() + "<convertOOXMLToDataXML>"
                    + "[ERROR]: line " + exception.getLineNumber() + ", row"
                    + exception.getColumnNumber() + ": " + exception.getMessage());
        }

        // This method is called when non-recoverable errors occur.
        @Override
        public void fatalError(SAXParseException exception) throws SAXException {
            Logger.err(DocxUtil.class.getCanonicalName() + "<convertOOXMLToDataXML>"
                    + "[FATAL]: line " + exception.getLineNumber() + ", row"
                    + exception.getColumnNumber() + ": " + exception.getMessage());
            throw (exception);
        }

        protected void addText(char arr[], int start, int length){
            append(new String(arr, start, length));
        }

        protected void openTag(String uri, String localName, String qName,
                Attributes atrbts) {
            StringBuilder str = new StringBuilder();
            str.append('<').append(qName);
            for (int i = 0; i < atrbts.getLength(); i++) {
                str.append(' ').append(atrbts.getQName(i)).append("=\"")
                        .append(atrbts.getValue(i)).append('"');
            }
            str.append('>');
            append(str);
        }

        protected void closeTag(String uri, String localName, String qName) {
            append(new StringBuilder().append("</").append(qName).append('>'));
        }

        protected abstract void append(CharSequence str);
    }
}
